package com.lhl.jwt.security.filters;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.lhl.jwt.service.JwtUserDetailsService;
import com.lhl.jwt.token.MobileCodeAuthenticationToken;
import org.springframework.security.authentication.AbstractAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.util.Assert;
import org.springframework.util.StreamUtils;
import org.springframework.util.StringUtils;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.Charset;


/**
 *  登录过滤器
 * @author king
 * 2019年8月17日
 */
public class MobileCodeAuthenticationFilter extends AbstractAuthenticationProcessingFilter {

	public static final String SPRING_SECURITY_FORM_MOBILE_KEY = "mobile";
	public static final String SPRING_SECURITY_FORM_CODE_KEY = "code";

	private String mobileParameter = SPRING_SECURITY_FORM_MOBILE_KEY;
	private String codeParameter = SPRING_SECURITY_FORM_CODE_KEY;
	private boolean postOnly = true;

	private JwtUserDetailsService jwtUserDetailsService;

	public MobileCodeAuthenticationFilter() {
		super(new AntPathRequestMatcher("/mobileCodeLogin", "POST"));
	}
	
	@Override
	public void afterPropertiesSet() {
		Assert.notNull(getAuthenticationManager(), "AuthenticationManager must be specified");
		Assert.notNull(getSuccessHandler(), "AuthenticationSuccessHandler must be specified");
		Assert.notNull(getFailureHandler(), "AuthenticationFailureHandler must be specified");
	}

	@Override
	public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
			throws AuthenticationException, IOException, ServletException {
		String body = StreamUtils.copyToString(request.getInputStream(), Charset.forName("UTF-8"));
		String mobile="", code="";
		if (StrUtil.isBlank(body)) {
			mobile = request.getParameter(mobileParameter);
			code = request.getParameter(codeParameter);
		} else {
			if(StringUtils.hasText(body)) {
				JSONObject jsonObj = JSONUtil.toBean(body.trim(),JSONObject.class);
				mobile = jsonObj.getStr(mobileParameter);
				code = jsonObj.getStr(codeParameter);
			}
		}
		AbstractAuthenticationToken authRequest = new MobileCodeAuthenticationToken(mobile.trim(),code.trim());
        // Allow subclasses to set the "details" property
		setDetails(request, authRequest);
		return this.getAuthenticationManager().authenticate(authRequest);
	}



	public JwtUserDetailsService getJwtUserDetailsService() {
		return jwtUserDetailsService;
	}

	public void setJwtUserDetailsService(JwtUserDetailsService jwtUserDetailsService) {
		this.jwtUserDetailsService = jwtUserDetailsService;
	}

	protected void setDetails(HttpServletRequest request,
							  AbstractAuthenticationToken authRequest) {
		authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
	}
}
